json_path = r'out\rk3568\suites\acts\acts\testcases'

# 作者： https://gitcode.com/code4lala
# 最新版本： https://gitcode.com/code4lala/oh-xts-automation/blob/master/run_xts.py
# 使用方法：
# 1.计算云编译xts
#       cd test/xts/acts/
#       ./build.sh product_name=rk3568 suite=xts_acts system_size=standard target_arch=arm target_subsystem=security
#       如果要编译64位的就把 target_arch=arm 改成 target_arch=arm64
# 2.windows通过samba运行xts
#       cd Z:\openharmony\master
#       python -u run_xts.py | tee xts-result.txt
#       python 加一个 -u 参数是因为不加的话，输出缓冲区会满了才打印导致输出乱序，加了-u就是禁用缓冲区
# 3.失败的场景下如何调试
#       先用python -u run_xts.py跑出来失败结果之后，在失败结果往前翻找到失败用例的安装命令和执行命令，举例：
#       hdc install C:\acts\huks_cases\ActsHuksSignVerifyBasicPromiseJSApiReformedTest.hap
#       hdc shell aa test -p com.example.hukssignverifybasicpromise -b com.example.hukssignverifybasicpromise -s unittest OpenHarmonyTestRunner -s timeout 1500000
#       然后找到失败用例的日志，举例：
#       OHOS_REPORT_STATUS: class=SecurityHuksRSASignExtendJsunit
#       OHOS_REPORT_STATUS: current=130
#       OHOS_REPORT_STATUS: id=JS
#       OHOS_REPORT_STATUS: numtests=130
#       OHOS_REPORT_STATUS: stack=    at AssertException (/mnt/disk/workspace/jenkins_ci_pool_high_002/harmony_master/out/rk3568/obj/test/xts/acts/security/security_huks_reformed_test/huks_signverify_promise_BasicTest/module_hukssignverify_promise_basic_js_reformed_test/assets/TestAbility/vendors_.js:4919:4919)
#           at anonymous (/mnt/disk/workspace/jenkins_ci_pool_high_002/harmony_master/out/rk3568/obj/test/xts/acts/security/security_huks_reformed_test/huks_signverify_promise_BasicTest/module_hukssignverify_promise_basic_js_reformed_test/assets/TestAbility/vendors_.js:5708:5708)
#           at anonymous (/mnt/disk/workspace/jenkins_ci_pool_high_002/harmony_master/out/rk3568/obj/test/xts/acts/security/security_huks_reformed_test/huks_signverify_promise_BasicTest/module_hukssignverify_promise_basic_js_reformed_test/assets/TestAbility/app_.js:3880:1)
#       OHOS_REPORT_STATUS: stream=Error in Security_HUKS_Cipher_AnonAttestation_0014, expect undefined equals 401
#       OHOS_REPORT_STATUS: test=Security_HUKS_Cipher_AnonAttestation_0014
#       OHOS_REPORT_STATUS_CODE: -2
#       OHOS_REPORT_STATUS: consuming=10
#       摘出来里边的class=SecurityHuksRSASignExtendJsunit和test=Security_HUKS_Cipher_AnonAttestation_0014并把这两个参数以下边的形式追加到hdc shell aa命令的最后边
#       -s class SecurityHuksRSASignExtendJsunit#Security_HUKS_Cipher_AnonAttestation_0014
#       这样先执行hdc install，再执行hdc shell aa命令就可以只跑一个用例了，如下示例：
#       PS C:\acts> hdc install C:\acts\huks_cases\ActsHuksSignVerifyBasicPromiseJSApiReformedTest.hap
#       [Info]App install path:C:\acts\huks_cases\ActsHuksSignVerifyBasicPromiseJSApiReformedTest.hap, queuesize:0, msg:install bundle successfully.
#       AppMod finish
#       PS C:\acts> hdc shell aa test -p com.example.hukssignverifybasicpromise -b com.example.hukssignverifybasicpromise -s unittest OpenHarmonyTestRunner -s timeout 1500000 -s class SecurityHuksRSASignExtendJsunit#Security_HUKS_Cipher_AnonAttestation_0014
#       start ability successfully.
#
#       OHOS_REPORT_SUM: 1
#       OHOS_REPORT_STATUS: class=SecurityHuksRSASignExtendJsunit
#
#
#       OHOS_REPORT_STATUS: class=SecurityHuksRSASignExtendJsunit
#       OHOS_REPORT_STATUS: current=1
#       OHOS_REPORT_STATUS: id=JS
#       OHOS_REPORT_STATUS: numtests=1
#       OHOS_REPORT_STATUS: stream=
#       OHOS_REPORT_STATUS: test=Security_HUKS_Cipher_AnonAttestation_0014
#       OHOS_REPORT_STATUS_CODE: 1
#
#
#       OHOS_REPORT_STATUS: class=SecurityHuksRSASignExtendJsunit
#       OHOS_REPORT_STATUS: current=1
#       OHOS_REPORT_STATUS: id=JS
#       OHOS_REPORT_STATUS: numtests=1
#       OHOS_REPORT_STATUS: stack=    at AssertException (/mnt/disk/workspace/jenkins_ci_pool_high_002/harmony_master/out/rk3568/obj/test/xts/acts/security/security_huks_reformed_test/huks_signverify_promise_BasicTest/module_hukssignverify_promise_basic_js_reformed_test/assets/TestAbility/vendors_.js:4919:4919)
#           at anonymous (/mnt/disk/workspace/jenkins_ci_pool_high_002/harmony_master/out/rk3568/obj/test/xts/acts/security/security_huks_reformed_test/huks_signverify_promise_BasicTest/module_hukssignverify_promise_basic_js_reformed_test/assets/TestAbility/vendors_.js:5708:5708)
#           at anonymous (/mnt/disk/workspace/jenkins_ci_pool_high_002/harmony_master/out/rk3568/obj/test/xts/acts/security/security_huks_reformed_test/huks_signverify_promise_BasicTest/module_hukssignverify_promise_basic_js_reformed_test/assets/TestAbility/app_.js:3880:1)
#       OHOS_REPORT_STATUS: stream=Error in Security_HUKS_Cipher_AnonAttestation_0014, expect undefined equals 401
#       OHOS_REPORT_STATUS: test=Security_HUKS_Cipher_AnonAttestation_0014
#       OHOS_REPORT_STATUS_CODE: -2
#       OHOS_REPORT_STATUS: consuming=14
#
#
#       OHOS_REPORT_STATUS: class=SecurityHuksRSASignExtendJsunit
#       OHOS_REPORT_STATUS: suiteconsuming=14
#
#
#       OHOS_REPORT_RESULT: stream=Tests run: 1, Failure: 1, Error: 0, Pass: 0, Ignore: 0
#       OHOS_REPORT_CODE: -1
#       OHOS_REPORT_STATUS: taskconsuming=14
#
#       TestFinished-ResultCode: 0
#       TestFinished-ResultMsg: your test finished!!!
#       user test finished.

# ChangeLog
# v2.4 适配多hap包场景，比如ActsHuksNdkTest.hap和ActsHuksNdkMainTest.hap两个安装包同包名，需要都安装上才能跑起来这个用例，单独安装任何一个都跑不起来用例
# v2.3 适配新的xts hits用例json写法
# v2.2 跑完一个xts之后就把测试套卸载，解决不同测试套同包名安装不上的问题。把目录名放到注释的最前边第一行
# v2.1 一个xts用例都没有跑到的话就报错
# v2.0 增加调试单个用例的指导
# v1.9 兼容没有testcase-timeout的场景，修复module-name场景使用错误的package-name参数问题
# v1.8 兼容旧的hap包json和新的hap包json，旧的是package-name，新的是module-name
# v1.7 遇到json字段失败的场景打日志并接续跑，不中断
# v1.6 xts编译命令suite=acts改为suite=xts_acts
# v1.5 默认改成hdc命令而不是hdc_std，上边注释编译命令改成32位的
# v1.4 修复子目录找不到文件的问题
# v1.3 install -p -> install
# v1.2 安装hap包不能再用-r选项了，改成-p选项
# v1.1 可以设置使用hdc还是hdc_std，gtest用例不删除整个目录，只删除用例和结果xml文件

import json
import os
import sys
import traceback

hdc_cmd='hdc'


def print_and_run(cmd: str):
    print(cmd)
    os.system(cmd)


def main():
    total_run_count = 0

    for root, _, files in os.walk(json_path):
        for f in files:
            if not f.endswith('.json'):
                continue
            current_json = os.path.join(root, f)
            total_run_count += 1
            print(f'{current_json} begin')
            try:
                with open(current_json, 'r', encoding='UTF-8') as json_file:
                    json_dict = json.load(json_file)
                if json_dict['driver']['type'] == 'OHJSUnitTest':
                    bundle_name = json_dict['driver']['bundle-name']
                    use_package_name = True

                    # 如果找不到 package-name 就用 module-name
                    try:
                        package_name = json_dict['driver']['package-name']
                    except KeyError as e:
                        if e.args[0] == 'package-name':
                            use_package_name = False
                            module_name = json_dict['driver']['module-name']
                        else:
                            raise e

                    # 如果找不到 testcase-timeout 就用 1500000
                    try:
                        testcase_timeout = json_dict['driver']['testcase-timeout']
                    except KeyError as e:
                        if e.args[0] == 'testcase-timeout':
                            testcase_timeout = 1500000
                        else:
                            raise e

                    for kits_element in json_dict['kits']:
                        if 'test-file-name' in kits_element:
                            for hap_name in kits_element['test-file-name']:
                                print_and_run(f'{hdc_cmd} install {os.path.join(root, hap_name)}')

                    if use_package_name:
                        print_and_run(f'{hdc_cmd} shell aa test -p {package_name} -b {bundle_name} ' +
                            f'-s unittest OpenHarmonyTestRunner -s timeout {testcase_timeout}')
                    else:
                        print_and_run(f'{hdc_cmd} shell aa test -m {module_name} -b {bundle_name} ' +
                            f'-s unittest OpenHarmonyTestRunner -s timeout {testcase_timeout}')
                    print_and_run(f'{hdc_cmd} uninstall {bundle_name}')
                elif json_dict['driver']['type'] == 'CppTest':
                    module_name = json_dict['driver']['module-name']
                    native_test_device_path = json_dict['driver']['native-test-device-path']
                    push_destination_path = f'{native_test_device_path}/{module_name}'
                    print_and_run(f'{hdc_cmd} shell rm -rf {push_destination_path} {push_destination_path}.xml')
                    print_and_run(f'{hdc_cmd} shell mkdir -p {native_test_device_path}')
                    print_and_run(f'{hdc_cmd} file send {os.path.join(root, module_name)} {push_destination_path}')
                    print_and_run(f'{hdc_cmd} shell chmod +x {push_destination_path}')
                    print_and_run(f'{hdc_cmd} shell {push_destination_path} --gtest_output=xml:{native_test_device_path}/')
                    print_and_run(f'{hdc_cmd} shell cat {push_destination_path}.xml')
            except KeyError as e:
                print(f'{current_json} fail! 找不到json字段值 {e}')
                print('调用栈如下')
                traceback.print_exc(file=sys.stdout)
                print(f'{current_json} 内容如下')
                print(json.dumps(json_dict, indent=2))
            except Exception as e:
                print(f'{current_json} fail! {e}')
                print('调用栈如下')
                traceback.print_exc(file=sys.stdout)
            else:
                print(f'{current_json} end')
    if total_run_count == 0:
        raise Exception(f'no test cases in folder {json_path}')
    else:
        print(f'run total {total_run_count} cases')


if __name__ == '__main__':
    exit(main())
